<script setup lang="ts">
import { usePriceComponentStore } from '@/stores/priceComponentStore';
import { storeToRefs } from 'pinia';
import PriceComponentsSum from '@/components/PriceComponentsSum/PriceComponentsSum.vue';
import PriceComponent from '@/components/PriceComponent/PriceComponent.vue';
import { computed, onMounted, watch } from 'vue';
import { SlickList, SlickItem } from 'vue-slicksort';

const priceComponentStore = usePriceComponentStore();
const { components, isLoading, shouldApiFail } =
  storeToRefs(priceComponentStore);

const basePriceComponent = computed(() =>
  Object.values(components.value).find((component) => component.readonly)
);

const newPriceComponent = computed(() =>
  Object.values(components.value).find((component) => component.isNew)
);

const sortableComponentIds = computed({
  get(): { id: number }[] {
    return Object.values(components.value)
      .filter((component) => !component.isNew && !component.readonly)
      .sort((componentA, componentB) => componentA.order - componentB.order)
      .map((component) => ({
        id: component.id,
      }));
  },
  set(componentIds: { id: number }[]): void {
    priceComponentStore.bulkUpdate(
      componentIds.map((component, index) => ({
        id: component.id,
        order: index + 1,
      }))
    );
  },
});

watch(
  components,
  () => {
    if (!Object.values(components.value).find((component) => component.isNew)) {
      priceComponentStore.addComponent({
        label: '',
        value: '',
        readonly: false,
        isNew: true,
      });
    }
  },
  { immediate: true, deep: true }
);

onMounted(() => priceComponentStore.getComponents());
</script>

<template>
  <div class="price-components">
    <div class="price-components__header"><h3>Price components</h3></div>
    <div class="price-components__body">
      <template v-if="isLoading">Loading...</template>
      <template v-else>
        <PriceComponentsSum />
        <PriceComponent
          v-if="basePriceComponent"
          :key="basePriceComponent.id"
          :componentId="basePriceComponent.id"
        />
        <SlickList
          axis="y"
          class="price-components__components"
          v-model:list="sortableComponentIds"
          :useDragHandle="true"
        >
          <SlickItem
            v-for="(component, index) in sortableComponentIds"
            :key="component.id"
            :index="index"
          >
            <PriceComponent :key="component.id" :componentId="component.id" />
          </SlickItem>
        </SlickList>
        <PriceComponent
          :key="newPriceComponent.id"
          :componentId="newPriceComponent.id"
        />
      </template>
    </div>
    <div class="price-components__footer">
      <strong>Helper</strong>
      <div>
        <label for="toggle-api">Should API requests fail?</label>
        <input
          type="checkbox"
          name="toggle-api"
          id="toggle-api"
          :value="shouldApiFail"
          @change="priceComponentStore.toggleShouldApiFail"
        />
      </div>
      <button
        name="restart"
        @click="priceComponentStore.getComponents"
        :disabled="isLoading"
      >
        Reload
      </button>
    </div>
  </div>
</template>

<style scoped lang="scss">
.price-components {
  width: 100%;
  max-width: 1000px;
  min-width: 500px;
  border: 1px solid black;
  border-radius: 5px;
  position: relative;
  margin: 1rem auto;

  &__header {
    position: absolute;
    display: flex;
    background-color: #fff;
    left: 50%;
    transform: translate(-50%, -50%);
    align-items: center;
    padding: 0 1rem;
  }

  &__body {
    padding: 3rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  &__footer {
    padding: 3rem;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1rem;
  }

  &__components {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }
}
</style>
